/*
SSD1289 3.2" TFT LCD Functions for PIC32MX795F512L PMP
Copyright (C) 2012 Craig Dawson, Aaron Mohtar, Craig Peacock

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include "lcdText.h"

//-------------------------------
// Usage: lcdWriteChar('R',10,20,BLACK,WHITE);
// Prints 'R' at (10,20) in black agianst white background
// (x,y) is Top, Left corner of character
//-------------------------------
void lcdWriteChar(unsigned char c, unsigned int x, unsigned int y, int fcolor, int bcolor)
{
    int i, j;
    unsigned int nCols, nRows, nBytes, Word0, Word1;
    unsigned char PixelRow, Mask;
    unsigned char *pFont, *pChar;

    //Set pointer to font table
    pFont = *FONT8x8;

    //get the nCol, nRows and nBytes
    nCols = *pFont;
    nRows = *(pFont + 1);
    nBytes = *(pFont + 2);

    //Get pointer to last byte of desired char
    pChar = pFont + (nBytes * (c - 0x1f));

    //Address Set
    lcdSetAddress(x, y, (x + nRows - 1), (y + nCols - 1));

    lcdWriteCom(0x0022);


    //loop on each row, working backwards
    for (i = (nRows - 1); i >= 0; i--)
    {
        PixelRow = *pChar++;
        Mask = 0x80;
        for (j = 0; j < nCols; j += 1)
        {
            if ((PixelRow & Mask) == 0)
                Word0 = bcolor;
            else
                Word0 = fcolor;
            Mask = Mask >> 1;

            //LCD Portrait orientation
            delayUs(1);


           lcdWriteData(Word0);

           // lcdWriteData(Word1);

            /****************************
            COde for including orientation modes
            will print char. in Landscape orientation

            lcdSetPixel(x+i,y+j,Word0);
            lcdSetPixel(x+i,y+j+1,Word1);
             ********************************/
        }

    }
}


//-------------------------------
//Usage:
//char buffer[]="Hello";
//lcdWriteString(buffer,20,40,RED,BLACK);
//
//Prints string in buffer starting at (20,40)
//(x,y) => Top,Left of 1st character
//-------------------------------
unsigned int lcdWriteString(unsigned char *pString, int x, int y, int fcolor, int bcolor)
{
    unsigned char oldY, origX;
    origX = x;
    oldY = y;
    int counter = 0;

    while (*pString != 0x00)
    {
        switch (*pString)
        {
            case '\n':
                x = (origX - 8);
                y += 10;
                *pString++;
                break;
            default:
                lcdWriteChar(*pString++, x, y, fcolor, bcolor);
                counter++;
                break;
        }
        //advance x position & check if off the screen
        x = x + 8;
        if (x > 231)
        {
            x = origX;
            y += 10;
        }
        if (y >= 320) break;
    }
    return counter;
}//end of lcdWriteString()

//-------------------------------
//Usage: lcdWriteInt(32,20,40,RED,BLACK);
//
//Prints the unsigned integer 32 starting at (20,40)
//(x,y) => Top,Left of 1st character (inc space)
//-------------------------------
void lcdWriteInt(unsigned int num, unsigned int x, unsigned int y, unsigned int intWidth, unsigned int fcolor, unsigned int bcolor)
{
    unsigned char chars[intWidth];
    short counter = intWidth;
    short i = 0;

    if (num < 10)
    {
        lcdWriteChar((unsigned char)(48 + num), (x + (counter-1) * 8), y, fcolor, bcolor);
        return;
    }

    while (num != 0)
    {
        if (counter != 0)
            counter--;
        else
            break;

        chars[counter] = (unsigned char)((num % 10) + 48);
        num = num / 10;
    }

    for (i = 0; i <= counter; i++)
        lcdWriteChar(32, x + (i * 8), y, fcolor, bcolor); // place space, this ensures any previous numbers are completely overwritten

    for (i = counter; i < intWidth; i++)
        lcdWriteChar(chars[i], x + i * 8, y, fcolor, bcolor);
} //end of lcdWriteInt()

//-------------------------------
//Usage:
//unsigned int temperature = 25;
//lcdDisplayVariable("Temperature: ", temperature, 2, "deg",20,40,RED,BLACK);
//
//Prints Temperature: 25deg in red at (20,40)
//(x,y) => Top,Left of 1st character (inc space)
//-------------------------------
void lcdDisplayVariable(unsigned char *title, unsigned int value, unsigned intWidth, unsigned char *units, int x, int y, int fcolor, int bcolor)
{
    int length = lcdWriteString(title, x, y, fcolor, bcolor);    // returns length of written string
    lcdWriteInt(value, x + length * 8, y, intWidth, fcolor, bcolor);
    lcdWriteString(units, x + length * 8 + intWidth * 8, y, fcolor, bcolor);
} //end of lcdDisplayValue()
